package com.example.demo.stream;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author FENGYU
 * @description
 * @date 2023-09-26 15:11
 */
public class StreamTest {

    public static void main(String[] args) {
        map();
    }

    public static void filter() {
        // filter：筛选，是按照一定的规则校验流中的元素，将符合条件的元素提取到新的流中的操作。
        List<Integer> list = Arrays.asList(6, 7, 3, 8, 1, 2);
        Stream<Integer> stream = list.stream();
        stream.filter(x -> x > 5).forEach(System.out::println);

    }

    public static void map() {

        //①map：一个元素类型为 T 的流转换成元素类型为 R 的流，这个方法传入一个Function的函数式接口，接收一个泛型T，返回泛型R，map函数的定义，返回的流，表示的泛型是R对象；
        //<R> Stream<R> map(Function<? super T, ? extends R> mapper);

        //将String转化为People对象
        Stream.of("小王:18", "小杨:20").map(s -> {
            String[] str = s.split(":");
            People people = new People(str[0], Integer.valueOf(str[1]));
            return people;
        }).forEach(people -> System.out.println("people = " + people));

        List<String> wordList = new ArrayList<>();
        wordList.add("dfsdf");
        wordList.add("dfsgfgdf");
        wordList.add("dfxcvxc43sdf");

        List<String> output = wordList.stream().map(String::toUpperCase).collect(Collectors.toList());

        System.out.println(wordList);
        System.out.println(output);

        List<People> peopleList = new ArrayList<>();
        peopleList.add(new People("ffd",18));
        peopleList.add(new People("fffsdfsdd",19));
        peopleList.add(new People("fvvvvvvvvfd",29));


        List<People> peopleList2 = peopleList.stream().map(people ->{
            people.setAge(people.getAge()+10);
            return people;
        }).collect(Collectors.toList());

        System.out.println(peopleList);
        System.out.println(peopleList2);
    }

    public static void flatMap() {
        //接收一个函数作为参数，将流中的每个值都换成另一个流，然后把所有流连接成一个流。

        List<String> list1 = Arrays.asList("m,k,l,a", "1,3,5,7");
        List<String> listNew = list1.stream().flatMap(s -> {
            // 将每个元素转换成一个stream
            String[] split = s.split(",");
            Stream<String> s2 = Arrays.stream(split);
            return s2;
        }).collect(Collectors.toList());

        System.out.println("处理前的集合：" + list1);      //["m,k,l,a", "1,3,5,7"]
        System.out.println("处理后的集合：" + listNew);    //["m", "k", "l", "a", "1", "3", "5", "7"]

    }

    public static void peek() {
        //peek 操作接收的是一个 Consumer<T> 函数。顾名思义 peek 操作会按照 Consumer<T> 函数提供的逻辑去消费流中的每一个元素，同时有可能改变元素内部的一些属性。
        Stream<String> stream = Stream.of("hello", "felord.cn");
        stream.peek(System.out::println);

        System.out.println("---------------------");

        Stream<String> stream2 = Stream.of("hello", "felord.cn");
        stream2.peek(System.out::println).collect(Collectors.toList());   //控制台打印内容如下：  hello  felord.cn
        //重点：peek VS map
        //peek 操作 一般用于不想改变流中元素本身的类型或者只想元素的内部状态时；
        //而 map 则用于改变流中元素本身类型，即从元素中派生出另一种类型的操作。
    }


    static class People {
        private String name;
        private int age;

        public People(String name, Integer age) {
            this.age = age;
            this.name = name;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getAge() {
            return age;
        }

        public void setAge(int age) {
            this.age = age;
        }

        @Override
        public String toString() {
            return "People{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
}


